'''Module for keeping track of node up/down status.

Goal is to distribute task of constantly pinging nodes to see if they're ok.
There are three loosely related questions:
    is the node up?
    is monitord running on it?
    can we SSH into it? 
The last can't be answered with 100% accuracy without having the private key.

'''
import commands
import neighbours
import ping
import conf

cache = {} # as usual, we only send changes to the server

def gather():
    '''Check how the nodes we're responsible for are doing.

To keep the architecture simple, for now the nodes are arranged in a 
unidirectional ring. Each node is responsible for watching the node below it,
skipping over any nodes it detects as down or not having monitord running.
    '''
    lookup = {True: {True:'up -monitord', False:'up -ssh -monitord'},
              False:{True:'-ping +ssh', False:'down'}}
    data = {} 
    nodes = neighbours.nodes
    
    count=0
    for node in nodes:
        count+=1
        if count>conf.MAX_WATCH_NODES: break

        up = ping.ping(node)
        ssh = ping.has_ssh(node)
        mond = ping.has_monitord(node)

        # if it's got monitord, it can handle things further down the list
        if mond: 
            break
        # otherwise, we need to keep the server informed and keep scanning
        state=lookup[up][ssh]
        # don't bother telling the server things it knows
        if node in cache:
            if cache[node]==state: continue
        # do tell it new stuff, but cache it for later
        cache[node] = data[node] = state

    return data
